package cn.edu.lcu.cs.javaprogramming.oop.innerclass;

import lombok.extern.java.Log;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import java.time.LocalDate;
import java.util.Arrays;
import java.util.Comparator;

/**
 * 雇员数组的排序。
 *
 * @author ling
 * @date 2022/3/13 22:21
 */
// Lombok注解，添加日志功能。
// 日志打印，比直接控制台输出效果好很多。
@Log
class EmployeeSortingDemo {
    Employee[] employees;

    /**
     * 在每个测试方法执行前都先执行本方法，进行必要的初始化工作。 <br>
     * 创建雇员的数组，添加若干个实例进去。
     */
    @BeforeEach
    void setUp() {
        Employee zhao = Employee.builder().name("zhao").address("聊城大学西校").birthdate(LocalDate.of(2000, 1, 1)).salary(4000.).gender("男").build();
        Employee qian = Employee.builder().name("qian").address("聊城大学东校").birthdate(LocalDate.of(2008, 8, 8)).salary(3000.).gender("女").build();
        Employee sun = Employee.builder().name("sun").address("聊城大学东昌学院").birthdate(LocalDate.of(2008, 9, 1)).salary(2000.).gender("男").build();
        Employee li = Employee.builder().name("li").address("聊城技师学院").birthdate(LocalDate.of(2007, 8, 31)).salary(15000.).gender("女").build();
        employees = new Employee[4];
        employees[0] = zhao;
        employees[1] = qian;
        employees[2] = sun;
        employees[3] = li;
    }

    /**
     * 在每个测试方法之后执行，打印排序后的结果。
     */
    @AfterEach
    void tearDown() {
        for (Employee employee : employees) {
            System.out.println(employee);
        }
        System.out.println("-------------------华丽丽的分隔线---------------------------");
    }

    /**
     * 根据年龄递增排序
     */
    @Test
    void sortByAgeAscend() {
        log.info("根据年龄递增排序");

        // 使用java.util.Arrays#sort(T[], java.util.Comparator<? super T>)进行排序。
        // 参数1：待排序的数组
        // 参数2：比较器，用于对两个实例进行大小比较

        Arrays.sort(employees, Comparator.comparing(Employee::getBirthdate).reversed());
    }

    /**
     * 根据年龄递减排序
     */
    @Test
    void sortByAgeDescend() {
        log.info("根据年龄递减排序");

        // 比较年龄，但是此种方法有问题，因为 getAge()只返回了年数，如果同年出生就没法比较了。
        //Arrays.sort(employees, (e1, e2) -> e1.getAge() - e2.getAge());

        // 直接用birthdate进行年龄比较最合适
        //Arrays.sort(employees, (e1, e2) -> e1.getBirthdate().compareTo(e2.getBirthdate()));

        Arrays.sort(employees, Comparator.comparing(Employee::getBirthdate));
    }

    @Test
    void sortBySalary() {
        log.info("根据工资递增排序");

        // Lambda表达式，实现java.util.Comparator接口
        //Arrays.sort(employees, (e1, e2) -> (int) (e1.getSalary() - e2.getSalary()));

        // Employee类中有一个现成的compareBySalary静态方法，
        // 返回类型与参数定义与java.util.Comparator相同，
        // 直接引用它就行了，没必要再去重新定义。
        Arrays.sort(employees, Employee::compareBySalary);
        //Arrays.sort(employees, Comparator.comparing(Employee::getSalary));
    }


    @Test
    void sortBySalaryDescend() {
        log.info("根据工资递减排序");

        Arrays.sort(employees, (e1, e2) -> (int) (e2.getSalary() - e1.getSalary()));
        //Arrays.sort(employees, Comparator.comparing(Employee::getSalary).reversed());
    }

    @Test
    void sortByName() {
        log.info("根据姓名递增排序");
        Arrays.sort(employees, Comparator.comparing(Employee::getName));
    }

}